# -*- coding: utf-8 -*-


import os
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtXml import *
import treeoftable

DESCRIPTION, STARTPOINT, DEADLINE, PRIORITY, UNIT, ESTIMATION = range(6)

class AimModel(treeoftable.TreeOfTableModel):

    @staticmethod
    def serialize(node):
        name        = node.name
        description = node.field(DESCRIPTION)
        startpoint  = node.field(STARTPOINT)
        deadline    = node.field(DEADLINE)
        priority    = node.field(PRIORITY)
        if isinstance(node, treeoftable.ComplexNode):
            result = "<ComplexAim name=\"%s\" description=\"%s\" startpoint=\"%s\" deadline=\"%s\" priority=\"%s\">\n" % (name, description, startpoint, deadline, priority)
            for i in range(node.childrenCount()):
                result += AimModel.serialize(node.childAtRow(i))
            result += "</ComplexAim>\n"
        elif isinstance(node, treeoftable.Node):
            unit        = node.field(UNIT)
            estimation  = node.field(ESTIMATION)
            result = "<MeasurableAim name=\"%s\" description=\"%s\" startpoint=\"%s\" deadline=\"%s\" priority=\"%s\" unit=\"%s\" estimation=\"%s\"/>\n" % (name, description, startpoint, deadline, priority, unit, estimation)

        return result

    @staticmethod
    def deserialize(strNode):
        document = QDomDocument()
        error    = None

        if not document.setContent(strNode, False):
            return None
        
        return AimModel.DOMElement2Node(document.documentElement()) 


    @staticmethod
    def DOMElement2Node(element):
        result  = None
        fields  = []
        name    = unicode(element.attribute("name"))
        tagName = element.tagName()

        fields.append(unicode(element.attribute("description")))
        fields.append(unicode(element.attribute("startpoint")))
        fields.append(unicode(element.attribute("deadline")))
        fields.append(unicode(element.attribute("priority")))
        if tagName == "ComplexAim":
            result    = treeoftable.ComplexNode(name, fields, PRIORITY)
            childNode = element.firstChild()
            while not childNode.isNull():
                childElement = childNode.toElement()
                if childElement.tagName() in ("ComplexAim", "MeasurableAim"):
                    result.insertChild(AimModel.DOMElement2Node(childElement))
                childNode = childNode.nextSibling()
        elif tagName == "MeasurableAim":
            fields.append(unicode(element.attribute("unit")))
            fields.append(unicode(element.attribute("estimation")))   
            result = treeoftable.Node(name, fields, PRIORITY)

        return result
        

    def __init__(self, parent=None):
        super(AimModel, self).__init__(parent)
        self.headers = ["Tasks", "Description", "Startpoint", "Deadline", "Priority", "Unit", "Estimation"]
        self.columns = 7

    def data(self, index, role):
        if role == Qt.TextAlignmentRole:
            return QVariant(int(Qt.AlignTop|Qt.AlignLeft))
        if role == Qt.DecorationRole:
            return QVariant()
        if role != Qt.DisplayRole:
            return QVariant()
        node = self.nodeFromIndex(index)
        assert node is not None
        if index.column() == 0:
            return QVariant(node.name)
        column = index.column() - 1
        if isinstance(node, treeoftable.ComplexNode):
            if column < node.fieldsCount():
              return QVariant(node.field(column))
            return  QVariant(QString(""))
        return QVariant(node.field(column))

    def resetToNew(self):
      self.root = treeoftable.ComplexNode("main", ["", "", "", ""])
      firstNode = treeoftable.ComplexNode("New aim", ["Put description here", "01.01.2010", "01.01.2011", "10"])
      self.root.insertChild(firstNode)

    # loading data from XML - file.
    def load(self, fname): 
        self.root = treeoftable.ComplexNode("")
        dom       = QDomDocument()
        error     = None
        fh        = None
        try:
            fh = QFile(fname)
            if not fh.open(QIODevice.ReadOnly):
                raise IOError, unicode(fh.errorString())
            if not dom.setContent(fh):
                raise ValueError, "could not parse XML"
        except (IOError, OSError, ValueError), e:
            error = "Failed to import: %s" % e
        finally:
            if fh is not None:
                fh.close()
            if error is not None:
                return False, error
        try:	
            root = dom.documentElement()
            if root.tagName() != "Aims":
                raise ValueError, "not a Aims XML file"
            node = root.firstChild()
            while not node.isNull():
                if node.toElement().tagName() == "ComplexAim":
                    self.root = AimModel.DOMElement2Node(node.toElement())
                    break
                node = node.nextSibling()
        except ValueError, e:
            self.reset()
            return False
        self.reset()
        return True


class TreeOfTableWidget(QTreeView):

    def __init__(self, filename=None, parent=None):
        super(TreeOfTableWidget, self).__init__(parent)
        self.setSelectionBehavior(QTreeView.SelectItems)
        self.setUniformRowHeights(True)
        model = AimModel(self)
        self.setModel(model)
        try:
            if filename is not None:
                model.load(filename)
            else:
                model.resetToNew()
        except IOError, e:
            QMessageBox.warning(self, "Aim Info - Error", unicode(e))
        self.connect(self, SIGNAL("activated(QModelIndex)"), self.activated)
        self.connect(self, SIGNAL("expanded(QModelIndex)"), self.expanded)
        self.setItemsExpandable(False)
        self.expandAll()
        self.expanded()

    def currentNode(self):
        return self.model().nodeFromIndex(self.currentIndex())

    def activated(self, index):
        self.emit(SIGNAL("activated"))

    def expanded(self):
        for column in range(self.model().columnCount(QModelIndex())):
            self.resizeColumnToContents(column)